Skip to content

Fix length of non-beat clips in the pattern editor#8369

Open
Itreza2 wants to merge 8 commits into
LMMS:masterfrom
Itreza2:clip-length-pattern
Open

Fix length of non-beat clips in the pattern editor#8369
Itreza2 wants to merge 8 commits into
LMMS:masterfrom
Itreza2:clip-length-pattern

Conversation

@Itreza2
Copy link
Copy Markdown
Contributor

@Itreza2 Itreza2 commented May 4, 2026

This PR is correcting the following:

  • The melody / automation / sample clips were displayed with a constant length. They now scale with the pattern length.
  • The length of melody / automation clips was independent from the number of steps in the pattern, which was causing some weird and unexpected behaviors.

Before:

2026-05-04.17-43-10.mp4

After:

2026-05-04.17-45-30.mp4

To my knowledge, no currently opened issue would be resolved by this PR, but I could be wrong.

@Monospace-V
Copy link
Copy Markdown
Member

Monospace-V commented May 4, 2026

Is this likely to break backward compatibility with projects that have a different step size in pattern editor than its contents? I ask because I probably have projects like that.
Also can you describe what you mean by "unexpected and weird behaviours"?

@Itreza2
Copy link
Copy Markdown
Contributor Author

Itreza2 commented May 4, 2026

Also can you describe what you mean by "unexpected and weird behaviours"?

Sure !
For instance, when you add notes to a melody clip (or nodes to an automation clip) that belong to a pattern, the clip size is automatically updated the same way as in the song editor. This will not add steps to the pattern, but the duration of the pattern is the length of its longest clip, so you can end in a situation where the playback arrow just continue out of the window, which I find quite unexpected and weird.
On the contrary, reducing the amount of steps will not reduce the melody / automation / sample lengths (and the pattern duration), but only the beat clips lengths.

Maybe my explanations are confusing 😅​. I will capture a video when able to, to show what I mean.

@Itreza2
Copy link
Copy Markdown
Contributor Author

Itreza2 commented May 4, 2026

Is this likely to break backward compatibility with projects that have a different step size in pattern editor than its contents?

You mean if you have clips inside a pattern that are longer than the amount of steps in the pattern ? Then yes, this would break your project and you would have to manually add steps to the pattern.

@Itreza2
Copy link
Copy Markdown
Contributor Author

Itreza2 commented May 4, 2026

I will capture a video when able to, to show what I mean.

Like promised, I have updated the description with a before / after demonstration.

@regulus79
Copy link
Copy Markdown
Member

I think this looks pretty cool!

@bratpeki bratpeki self-assigned this May 16, 2026
@bratpeki
Copy link
Copy Markdown
Member

Glad this has been addressed!
I also haven't seen any open PRs regarding this.

Comment thread src/gui/editors/PatternEditor.cpp Outdated
auto mClip = static_cast<MidiClip*>(track->getClip(m_ps->currentPattern()));
m_maxClipLength = std::max(m_maxClipLength, static_cast<tick_t>(mClip->length()));
}
else
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This else covers every track type that isn't Instrument, which btw...

enum class Type
{
	Instrument,
	Pattern,
	Sample,
	Event,
	Video,
	Automation,
	HiddenAutomation,
	Count
} ;

Cursed, cursed, cursed!

@messmerd is it a safe assumption that this else only catches Sample and Automation?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I completely missed the fact that there were so many types of tracks 😅 (What even is a Video or Count track?)

I guess it would indeed do no harm to be explicit here, as we only only resize Sample and Automation clips for visual purposes (and all these other types, even if they happened to be present in the pattern store, are never displayed anyway).
But in the end, it doesn't change much.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, maybe an else if for samples and automation, and an else assert(false) since we're not supposed to reach that for now.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also use a switch statement:

switch (track->type())
{
	case Track::Type::Instrument:
	{
		auto mClip = static_cast<MidiClip*>(track->getClip(m_ps->currentPattern()));
		m_maxClipLength = std::max(m_maxClipLength, static_cast<tick_t>(mClip->length()));
		break;
	}
	case Track::Type::Sample: [[fallthrough]];
	case Track::Type::Automation:
	{
		auto clip = track->getClip(m_ps->currentPattern());
		clip->updateLength();
		break;
	}
	default:
		assert(false);
		break;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the m_maxClipLength variable be updated for sample and automation tracks too?

Copy link
Copy Markdown
Contributor Author

@Itreza2 Itreza2 May 16, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well... actually yes...

I'm a little embarrassed by my self from 2 weeks ago. (I believe I somehow thought that it had an impact on the pattern length ?!)

(Edit: I fact my past me just left this block as it was previously, which is pretty reasonable)

Comment thread src/gui/clips/AutomationClipView.cpp
Comment thread src/core/SampleClip.cpp Outdated

SampleClip::SampleClip(Track* _track, Sample sample, bool isPlaying)
: Clip(_track)
, m_sampleTrack(_track)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Clip already stores a Track, and has a getter called getTrack().

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the first thing I should have checked. Thank you for pointing it out.

Comment thread src/gui/editors/PatternEditor.cpp Outdated
auto mClip = static_cast<MidiClip*>(track->getClip(m_ps->currentPattern()));
m_maxClipLength = std::max(m_maxClipLength, static_cast<tick_t>(mClip->length()));
}
else
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could also use a switch statement:

switch (track->type())
{
	case Track::Type::Instrument:
	{
		auto mClip = static_cast<MidiClip*>(track->getClip(m_ps->currentPattern()));
		m_maxClipLength = std::max(m_maxClipLength, static_cast<tick_t>(mClip->length()));
		break;
	}
	case Track::Type::Sample: [[fallthrough]];
	case Track::Type::Automation:
	{
		auto clip = track->getClip(m_ps->currentPattern());
		clip->updateLength();
		break;
	}
	default:
		assert(false);
		break;
}

@messmerd messmerd changed the title Fix lenght of non-beat clips in the pattern editor Fix length of non-beat clips in the pattern editor May 16, 2026
Copy link
Copy Markdown
Member

@bratpeki bratpeki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving for code and testing.

@bratpeki bratpeki requested a review from messmerd May 18, 2026 16:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants